# 文件相关知识

# 一、文件的编码
"""
思考: 计算机只能识别0和1, 那么我们丰富的文本文件是如何被计算机所识别并存入到硬盘中的呢？
答案: 使用编码技术将内容翻译乘0和1存入。

编码技术就是翻译的规则，记录如何将内容翻译成二进制, 以及如何将二进制翻译回原本的内容
可以想象成一个"密码本",
比方说当“我”通过密码本翻译成“1101”
...
计算机中有许多的编码技术(不同的密码本)
* UTF-8(目前是全球通用的编码格式)
* GBK
* BIG5
* ...
"""

# 二、文件操作的相关操作

# 2.1 打开文件
"""
使用open函数, 可以打开一个已经存在的文件, 或者创建一个新的文件, 语法如下:
文件对象 = open(name, mode, encoding)
name: 文件名
mode: 打开方式。
    * 'r'只读
    * 'w': 文件存在则打开文件, 并从头开始编辑, 原有的内容会被删除。如果文件不存在则创建文件
    * ‘a’: 打开一个文件，然后追加写入。如果文件不存在则创建文件
encoding: 编码格式(推荐使用UTF-8)
"""

f = open("./readme.txt", "r", encoding="UTF-8")
print(f"文件对象的类型:{type(f)}")

# 2.2 读操作
"""
1. read方法:
字符串 = 文件对象.read(num)
num表示=要从文件中读取的数据的长度（单位是字节）, 如果不传num, 那么就表示读取文件中的所有数据

2. readlines方法:
将文件中的每一行都存放在列表中

3. readline方法:
只读取一行，返回的是字符串对象

4. for循环读取文件行
for line in 文件对象:
    print(line)

注意: 如果程序中调用了两次read, 第一次正常读, 第二次会从上一次读完的地方继续向后读取...
"""
# read方法演示
# print(f"文件的内容:{f.read()}") # 读取所有内容

# readlines方法演示
# lines = f.readlines()
# print(f"文件的内容:{lines}, {type(lines)}")

# readline方法演示
# line1 = f.readline()
# line2 = f.readline()
# line3 = f.readline()
# line4 = f.readline()
# line5 = f.readline()
# print(f"第一行:{line1}")
# print(f"第二行{line2}")
# print(f"第三行:{line3}")
# print(f"第四行:{line4}")
# print(f"第五行:{line5}")
#
# for line in f:
#     print(line)

# 2.3 文件关闭
"""
语法:
对象.close()

注意:
如果不调用close, 同时程序没有停止, 那么这个文件将一直被Python程序占用
"""

# 2.4 with open方法
"""
语法:
with open(参考open方法) as 命名文件对象:
    文件的相关操作    

通过在with open的语句块中对文件进行操作，
在操作完成之后自动关闭close文件，避免忘记close
"""

# 练习案例
# 要求: 统计words.txt文件中“itheima”出现的次数
# f = open("./words.txt", "r", encoding="UTF-8")

# 方法1: 获取整个文本
# get_all = f.read()
# print(f"itheima出现的次数:{get_all.count('itheima')}")

# 方法2； 一行一行统计
# f = open("words.txt", "r", encoding="UTF-8")
# count = 0
# for line in f:
#     line = line.strip()  # 去掉行首尾空格和换行等空白字符
#     words = line.split(" ")  # words是列表
#     for word in words:
#         if word == 'itheima':
#             count += 1
# print(f"itheima出现的次数:{count}")
# f.close()

# 三、文件写操作
"""
write方法
文件对象.write(写入字符串)
文件对象.flush()

注意: 
1. 直接调用write方法，内容并未真正写入文件，为了提高IO效率，而是会将写入的内容存放在
    缓冲区中。调用flush函数可以将缓冲区的内容刷新到文件中
2. close方法内置了flush方法
"""
# 打开一个不存在t1.txt文件
# f = open("t1.txt", "w", encoding="UTF-8")
# # 写入
# f.write("hello Python")
# # 刷新缓冲区
# f.flush()
# # 关闭文件
# f.close()

# 打开一个存在t1.txt文件
f = open("t1.txt", "w", encoding="UTF-8")
f.write("666666666666666666666666666666666666")
f.flush()
f.close()
# w模式的两个特点
# 1. 文件不存在会自动创建
# 2. 文件存在，在向文件写时，会先清空文件的内容在写入

# 四、文件的追加操作
"""
1. 文件不存在会自动创建文件
2. 不会清空原有的内容，而是在文件末尾追加写入
"""
# f = open("./t1.txt", "a", encoding="UTF-8")
# f.write("这是一条追加写入的message")
# f.flush()
# f.close()

# 五、综合案例
# 要求: 读取bill.txt文件,将不是测试的行都写入到bill.txt.bak中
fr = open("bill.txt", "r", encoding="UTF-8")
fw = open("bill.txt.bak", "w", encoding="UTF-8")

for line in fr:
    line = line.strip() # 清空首尾空白字符
    if line.split(",")[-1] == "测试":
        continue
    fw.write(line)
    fw.write('\n')
fw.close()
fr.close()
